{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import panel as pn\n",
    "pn.extension()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `Column` layout allows arranging multiple panel objects in a vertical container. It has a list-like API with methods to `append`, `extend`, `clear`, `insert`, `pop`, `remove` and `__setitem__`, which make it possible to interactively update and modify the layout.\n",
    "\n",
    "#### Parameters:\n",
    "\n",
    "For details on other options for customizing the component see the [layout](../../how_to/layout/index.md) and [styling](../../how_to/styling/index.md) how-to guides.\n",
    "\n",
    "* **`objects`** (list): The list of objects to display in the Column, should not generally be modified directly except when replaced in its entirety.\n",
    "* **`scroll`** (boolean): Enable scrollbars if the content overflows the size of the container.\n",
    "* **`scroll_position`** (int): Current scroll position of the Column. Setting this value will update the scroll position of the Column. Setting to 0 will scroll to the top.\n",
    "* **`auto_scroll_limit`** (int): Max pixel distance from the latest object in the Column to activate automatic scrolling upon update. Setting to 0 disables auto-scrolling\n",
    "* **`scroll_button_threshold`** (int): Min pixel distance from the latest object in the Column to display the scroll button. Setting to 0 disables the scroll button.\n",
    "* **`view_latest`** (bool): Whether to scroll to the latest object on init. If not enabled the view will be on the first object.\n",
    "\n",
    "#### Methods:\n",
    "\n",
    "* **`scroll_to(index: int)`**: Column will scroll to the object at the specified index.\n",
    "\n",
    "___"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A `Column` layout can either be instantiated as empty and populated after the fact or using a list of objects provided as positional arguments. If the objects are not already panel components they will each be converted to one using the `pn.panel` conversion method."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "w1 = pn.widgets.TextInput(name='Text:')\n",
    "w2 = pn.widgets.FloatSlider(name='Slider')\n",
    "\n",
    "column = pn.Column('# Column', w1, w2, styles=dict(background='WhiteSmoke'))\n",
    "column"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In general it is preferred to modify layouts only through the provided methods and avoid modifying the ``objects`` parameter directly. The one exception is when replacing the list of ``objects`` entirely, otherwise it is recommended to use the methods on the ``Column`` itself to ensure that the rendered views of the ``Column`` are rerendered in response to the change. As a simple example we might add an additional widget to the ``column`` using the append method:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "w3 = pn.widgets.Select(options=['A', 'B', 'C'])\n",
    "column.append(w3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On a live server or in a notebook the `column` displayed above will dynamically expand in size to accommodate all three widgets and the title. To see the effect in a statically rendered page, we will display the column a second time:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "column"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In general a ``Column`` does not have to be given an explicit ``width``, ``height`` or ``sizing_mode``, allowing it to adapt to the size of its contents. However in certain cases it can be useful to declare a fixed-size layout, which its responsively sized contents will then fill, making it possible to achieve equal spacing between multiple objects:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pn.Column(\n",
    "    pn.Spacer(styles=dict(background='red'),   sizing_mode='stretch_both'),\n",
    "    pn.Spacer(styles=dict(background='green'), sizing_mode='stretch_both'),\n",
    "    pn.Spacer(styles=dict(background='blue'),  sizing_mode='stretch_both'),\n",
    "    height=300, width=200\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When no fixed size is specified the column will expand to accommodate the sizing behavior of its contents:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from bokeh.plotting import figure\n",
    "\n",
    "p1 = figure(height=150, sizing_mode='stretch_width')\n",
    "p2 = figure(height=150, sizing_mode='stretch_width')\n",
    "\n",
    "p1.line([1, 2, 3], [1, 2, 3])\n",
    "p2.scatter([1, 2, 3], [1, 2, 3])\n",
    "\n",
    "pn.Column(p1, p2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Lastly it is also possible to enable scrollbars on the `Column` container in case the content overflows the specified height and width:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pn.Column(\n",
    "    pn.Spacer(styles=dict(background='red'), width=200, height=200),\n",
    "    pn.Spacer(styles=dict(background='green'), width=200, height=200),\n",
    "    pn.Spacer(styles=dict(background='blue'), width=200, height=200),\n",
    "    scroll=True, height=420\n",
    ")"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
